package main

import (
	"gitee.com/kaylee595/gkaylee/kerr"
	"github.com/gin-gonic/gin"
	"log/slog"
	"net"
	"net/http"
	"time"
	"videoPlay/internal/config"
	"videoPlay/internal/dal"
	"videoPlay/internal/http/handlers"
)

func init() {
	dal.DB = dal.ConnectDB("sqlite.db")
	config.C = kerr.Must(config.LoadConfig(""))
}

const listingAddr = ":8080"

func main() {
	ip := kerr.Must(getInternalIP())
	if ip != "" {
		slog.Info("服务已启动", "本地访问", "http://localhost"+listingAddr, "内网访问", "http://"+ip+listingAddr)
	} else {
		slog.Info("服务已启动", "本地访问", "http://localhost"+listingAddr)
	}
	server := &http.Server{
		Addr:         listingAddr,
		Handler:      newGinEngine(config.C.WebStaticPath),
		WriteTimeout: 3 * time.Second,
	}
	err := server.ListenAndServe()
	if err != nil {
		slog.Error("服务启动失败", "err", err)
	}
}

func getInternalIP() (string, error) {
	interfaces, err := net.Interfaces()
	if err != nil {
		return "", err
	}

	for _, iface := range interfaces {
		if iface.Flags&net.FlagUp == 0 {
			continue // interface down
		}
		if iface.Flags&net.FlagLoopback != 0 {
			continue // loopback interface
		}
		addrs, err := iface.Addrs()
		if err != nil {
			return "", err
		}
		for _, addr := range addrs {
			var ip net.IP
			switch v := addr.(type) {
			case *net.IPNet:
				ip = v.IP
			case *net.IPAddr:
				ip = v.IP
			}
			if ip == nil || ip.IsLoopback() {
				continue
			}
			ip = ip.To4()
			if ip == nil {
				continue // not an ipv4 address
			}
			if ip[3] <= 1 {
				// 不要网关地址
				continue
			}
			return ip.String(), nil
		}
	}
	return "", nil
}

func newGinEngine(staticPath string) *gin.Engine {
	gin.SetMode(gin.ReleaseMode)
	engine := gin.New()

	// 中间件
	engine.Use(gin.Recovery())

	// 当无法路由到处理器时, 尝试从静态文件中获取
	staticDir := gin.Dir(staticPath, false)
	engine.NoRoute(func(c *gin.Context) {
		c.FileFromFS(c.Request.URL.Path, staticDir)
	})

	// 路由处理器
	handlers.Router(engine)
	return engine
}
